var ClickedElement = "day";
var lastEvent = moment();
var Category = (function () {
    function Category(_id, _name, _color) {
        this._id = _id;
        this._name = _name;
        this._color = _color;
        this.ID = _id;
        this.Color = _color;
        this.Name = _name;
    }
    return Category;
})();
var ServerEntry = (function () {
    function ServerEntry(entry) {
        this.entry = entry;
        this.ID = entry.ID;
        this.Title = entry.Title();
        this.Description = entry.Description();
        this.StartDate = moment(entry.StartDate()).toDate();
        this.EndDate = moment(entry.EndDate()).toDate();
        this.IsAllDay = entry.IsAllDay();
        this.Category = entry.Category();
    }
    return ServerEntry;
})();
var Appointment = (function () {
    function Appointment(sd) {
        this.sd = sd;
        var _this = this;
        this.Title = ko.observable();
        this.Description = ko.observable();
        this.StartDate = ko.observable(sd);
        this.EndDate = ko.observable(sd);
        this.Name = ko.observable();
        this.Email = ko.observable();
        this.Phone = ko.observable();
        this.IsAllDay = ko.computed(function () {
            return ((typeof _this.EndDate() === "undefined") && (typeof _this.StartDate() === "undefined"));
        });
        this.DisplayTitle = ko.computed(function () {
            if(_this.IsAllDay()) {
                return 'appointment request';
            } else {
                return moment(_this.StartDate()).format('H:mm ') + 'appointment request';
            }
        });
    }
    Appointment.prototype.refreshDateStrings = function () {
        this.StartDateString = this.StartDate().format('YYYY-MM-DD HH:mm');
        this.EndDateString = this.EndDate().format('YYYY-MM-DD HH:mm');
    };
    Appointment.prototype.app_click = function (day) {
        var app = this;
        if(globalViewModel.role != "editor" && globalViewModel.role != "owner") {
            return;
        }
        globalViewModel.view_app(this);
        $('#CAL-View-Appointment-Dialog').dialog({
            title: 'Appointment request',
            width: 400,
            buttons: [
                {
                    text: 'Accept',
                    click: function () {
                        var entry = new Entry();
                        if(globalViewModel.acceptAppintment(app, entry)) {
                            day.Entries.push(entry);
                            day.Apps.remove(app);
                        }
                        $(this).dialog('close');
                    }
                }, 
                {
                    text: 'Refuse',
                    click: function () {
                        if(globalViewModel.refuseAppintment(app)) {
                            day.Apps.remove(app);
                        }
                        $(this).dialog('close');
                    }
                }
            ]
        });
    };
    return Appointment;
})();
var Entry = (function () {
    function Entry(data, category) {
        if (typeof data === "undefined") { data = {
            ID: -1,
            StartDate: moment(),
            EndDate: moment(),
            Title: '',
            Description: '',
            IsAllDay: true
        }; }
        if (typeof category === "undefined") { category = {
            Name: "Default",
            Color: "red",
            ID: -1
        }; }
        this.data = data;
        this.category = category;
        var _this = this;
        this.ID = data.ID;
        this.Title = ko.observable(data.Title == null ? '' : data.Title);
        this.Description = ko.observable(data.Description);
        this.StartDate = ko.observable(data.StartDate);
        if(data.ID != -1) {
            this.EndDate = ko.observable(data.EndDate);
        } else {
            this.EndDate = ko.observable();
        }
        this.IsAllDay = ko.observable(data.IsAllDay);
        this.Category = ko.observable(category);
        this.DisplayTitle = ko.computed(function () {
            if(_this.IsAllDay()) {
                return _this.Title();
            } else {
                if(typeof _this.EndDate() === "undefined") {
                    return moment(_this.StartDate()).format('H:mm ') + _this.Title();
                } else {
                    return moment(_this.StartDate()).format('H:mm-') + moment(_this.EndDate()).format('H:mm ') + _this.Title();
                }
            }
        });
    }
    Entry.prototype.entry_click = function (day, event) {
        var isSaveButtonsDisabled = (globalViewModel.role != "editor" && globalViewModel.role != "owner");
        globalViewModel.edit_entry(this);
        var currentEntry = this;
        var oldEntry = new Entry();
        oldEntry.ID = this.ID;
        oldEntry.Title = ko.observable(currentEntry.Title());
        oldEntry.Description = ko.observable(currentEntry.Description());
        oldEntry.StartDate = ko.observable(currentEntry.StartDate());
        oldEntry.EndDate = ko.observable(currentEntry.EndDate());
        oldEntry.IsAllDay = ko.observable(currentEntry.IsAllDay());
        var isDataSaved = false;
        $('#CAL-Edit-Entry-Dialog').dialog({
            width: 600,
            title: 'Edit entry',
            autoResize: true,
            width: 400,
            left: 500,
            close: function () {
                if(!isDataSaved) {
                    currentEntry.ID = oldEntry.ID;
                    currentEntry.Title(oldEntry.Title());
                    currentEntry.Description(oldEntry.Description());
                    currentEntry.StartDate(oldEntry.StartDate());
                    currentEntry.EndDate(oldEntry.EndDate());
                    currentEntry.IsAllDay(oldEntry.IsAllDay());
                }
            },
            open: function () {
                $('#CAL-EditEntry-Title').keypress(function (event) {
                    if(event.which == 13) {
                        $('.ui-dialog-buttonpane button:last').trigger('click');
                        event.preventDefault();
                    }
                });
            },
            buttons: [
                {
                    text: "Save",
                    disabled: isSaveButtonsDisabled,
                    click: function () {
                        var entry = globalViewModel.edit_entry();
                        var startDate = moment(entry.StartDate().format('LL') + ", " + $('#CAL-EditEntry-StartDate').val());
                        var endDate = moment(entry.EndDate().format('LL') + ", " + $('#CAL-EditEntry-EndDate').val());
                        entry.StartDate(startDate);
                        entry.EndDate(endDate);
                        var apiurl = $('#UpdateEntryUrl');
                        if(apiurl.length) {
                            var url = apiurl.val();
                            var success = true;
                            var serverEntry = new ServerEntry(entry);
                            var myEntry = {
                                ID: serverEntry.ID,
                                Title: serverEntry.Title,
                                Description: serverEntry.Description,
                                StartDateString: entry.StartDate().format('YYYY-MM-DD HH:mm'),
                                EndDateString: entry.EndDate().format('YYYY-MM-DD HH:mm'),
                                IsAllDay: serverEntry.IsAllDay,
                                CategoryID: serverEntry.Category.ID
                            };
                            $.ajax({
                                type: "POST",
                                url: url,
                                data: ko.toJSON(myEntry),
                                contentType: "application/json; charset=utf-8",
                                dataType: "json",
                                success: function (response) {
                                    success = true;
                                },
                                error: function (resp) {
                                    success = false;
                                }
                            });
                            isDataSaved = true;
                        }
                        $(this).dialog("close");
                    }
                }, 
                {
                    text: "Cancel",
                    click: function () {
                        $(this).dialog("close");
                    }
                }
            ]
        });
    };
    Entry.prototype.delete_entry = function (day, event, mustConfirm) {
        if (typeof mustConfirm === "undefined") { mustConfirm = true; }
        if(!(globalViewModel.role == "editor" || globalViewModel.role == "owner")) {
            alert('You can not remove this entry. Only editors or the owner can remove entries of the calendars.');
            return;
        }
        var entry = this;
        var Confirm = false;
        if(mustConfirm) {
            Confirm = confirm("Are you sure you want to delete " + this.DisplayTitle() + "?");
        }
        if(Confirm || !mustConfirm) {
            var apiurl = $('#DeleteEntryUrl');
            var url = apiurl.val();
            url += "/" + this.ID;
            $.ajax({
                type: "POST",
                url: url,
                success: function (response) {
                    day.Entries.remove(entry);
                },
                error: function (resp) {
                    alert("You can't delete this entry.");
                }
            });
        }
    };
    return Entry;
})();
var Day = (function () {
    function Day(date, viewModel) {
        this.date = date;
        this.Date = date;
        this.ViewModel = viewModel;
        this.Entries = ko.observableArray();
        this.Apps = ko.observableArray();
    }
    Day.prototype.sortEntries = function () {
        this.Entries.sort(function (a, b) {
            a.StartDate().format('HHmm') > b.StartDate().format('HHmm') ? 1 : -1;
        });
        this.Entries.valueHasMutated();
    };
    Day.prototype.day_click = function (a, element) {
        if(globalViewModel.isCalendar) {
            this.show_entry_creation(a, element);
        } else {
            if(globalViewModel.isAppointment) {
                this.show_appointment_creation(a, element);
            }
        }
    };
    Day.prototype.show_appointment_creation = function (a, element) {
        var apps = this.Apps;
        var current_app = this.ViewModel.current_app;
        current_app().StartDate(this.Date.hours(9));
        current_app().EndDate(this.Date.hours(10));
        var app = current_app();
        $('#CAL-New-Appointment-Dialog').dialog({
            title: 'Create new apointment request',
            width: 400,
            buttons: [
                {
                    text: 'Send request',
                    click: function () {
                        var startDate = moment(app.StartDate().format('LL') + ", " + $('#CAL-NewApp-StartTime').val());
                        var endDate = moment(app.StartDate().format('LL') + ", " + $('#CAL-NewApp-EndTime').val());
                        app.StartDate(startDate);
                        app.EndDate(endDate);
                        app.refreshDateStrings();
                        if(globalViewModel.saveAppointmentRequestToServer(current_app())) {
                            apps.push(current_app());
                            current_app(new Appointment(moment().hours(9)));
                        }
                        $(this).dialog("close");
                    }
                }
            ]
        });
    };
    Day.prototype.show_entry_creation = function (a, element) {
        if(!(globalViewModel.role == "editor" || globalViewModel.role == "owner")) {
            return;
        }
        var currentDay = this;
        var current_entry = this.ViewModel.current_entry;
        current_entry().StartDate(this.Date);
        var vm = this.ViewModel;
        var entries = this.Entries;
        $('#CAL-New-Entry-Dialog').dialog({
            title: 'Create entry',
            autoResize: true,
            width: 400,
            left: 500,
            open: function () {
                $('#CAL-NewEntry-Title').keypress(function (event) {
                    if(event.which == 13) {
                        $('.ui-dialog-buttonpane button:last').trigger('click');
                        event.preventDefault();
                    }
                });
            },
            buttons: [
                {
                    text: "Create",
                    click: function () {
                        currentDay.SaveEntry(current_entry);
                        $(this).dialog("close");
                    }
                }
            ]
        });
    };
    Day.prototype.SaveEntry = function (current_entry) {
        var currentDay = this;
        var current_entry = this.ViewModel.current_entry;
        current_entry().StartDate(this.Date);
        var vm = this.ViewModel;
        var entries = this.Entries;
        var title = current_entry().Title();
        var startDate = current_entry().StartDate();
        var endDate = current_entry().EndDate();
        title = $.trim(title);
        var titleParts = title.split(' ');
        if(titleParts.length > 0) {
            var possibleTime = titleParts[0];
            var possibleTimeParts = possibleTime.split('-');
            var hasStartTime = possibleTimeParts.length >= 1;
            var hasEndTime = possibleTimeParts.length >= 2;
            var onlyStartTime = possibleTimeParts.length == 1;
            if(hasStartTime || hasEndTime) {
                for(var i = 0; i < possibleTimeParts.length; i++) {
                    var time = possibleTimeParts[i];
                    var extendedDate = moment().format('LL') + ', ' + time;
                    if(moment(extendedDate).isValid()) {
                        var timeParts = possibleTimeParts[i].split(':');
                        if(timeParts.length >= possibleTimeParts.length) {
                            var hour = parseInt(timeParts[0]);
                            var minute = parseInt(timeParts[1]);
                            if(!isNaN(hour) && !isNaN(minute) && hour < 24 && minute < 60 && hour >= 0 && minute >= 0) {
                                var timeStringLength = timeParts[0].length + timeParts[1].length + 2;
                                title = title.substring(timeStringLength, title.length);
                                if(i == 0) {
                                    startDate = moment(startDate).hours(hour).minutes(minute);
                                    console.log(startDate.format('YYYY MM DD H:mm') + ' ' + title);
                                    current_entry().IsAllDay(false);
                                } else {
                                    if(i == 1) {
                                        endDate = moment(endDate).hours(hour).minutes(minute);
                                        console.log(startDate.format('YYYY MM DD H:mm') + "-" + endDate.format('YYYY MM DD H:mm') + ' ' + title);
                                        current_entry().IsAllDay(false);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        current_entry().StartDate(startDate);
        current_entry().EndDate(endDate);
        if(typeof current_entry().StartDate() !== "undefined" && typeof current_entry().EndDate() === "undefined") {
            var st = moment(current_entry().StartDate());
            current_entry().EndDate(st.add('hours', 2));
            console.log(current_entry().EndDate().format('HH:mm:ss'));
        }
        current_entry().Title(title);
        if(vm.saveEntryToServer(current_entry())) {
            entries.push(current_entry());
            currentDay.sortEntries();
            vm.current_entry(new Entry());
        }
    };
    return Day;
})();
var Week = (function () {
    function Week(firstDayofWeek, viewModel) {
        this.firstDayofWeek = firstDayofWeek;
        this.FirstDay = firstDayofWeek;
        this.ViewModel = viewModel;
        this.Days = ko.observableArray();
        this.Days.push(new Day(moment(firstDayofWeek), this.ViewModel));
        for(var i = 1; i < 7; i++) {
            var day = new Day(moment(firstDayofWeek.add('d', 1)), this.ViewModel);
            this.Days.push(day);
            viewModel.daysArray.push(day);
        }
    }
    return Week;
})();
var ViewModel = (function () {
    function ViewModel(_year, _month, _role, _siteType) {
        this._year = _year;
        this._month = _month;
        this._role = _role;
        this._siteType = _siteType;
        this.siteType = _siteType;
        this.isAppointment = this.isCalendar = false;
        if(this.siteType == "calendar") {
            this.isCalendar = true;
        } else {
            if(this.siteType == "appointment") {
                this.isAppointment = true;
            }
        }
        this.role = _role;
        var now = new Date(Date.now());
        this.current_entry = ko.observable(new Entry());
        this.current_app = ko.observable(new Appointment(moment().hours(9)));
        this.edit_entry = ko.observable();
        this.view_app = ko.observable();
        this.daysArray = new Array();
        this.set_self(this);
        var monthFirstDay = moment([
            _year, 
            _month - 1
        ]);
        var weekDay = monthFirstDay.format('d');
        var daysFromPreviousMonth = 0;
        switch(weekDay) {
            case '0': {
                daysFromPreviousMonth = 6;
                break;
            }

            case '1': {
                daysFromPreviousMonth = 0;
                break;
            }

            case '2': {
                daysFromPreviousMonth = 1;
                break;
            }

            case '3': {
                daysFromPreviousMonth = 2;
                break;
            }

            case '4': {
                daysFromPreviousMonth = 3;
                break;
            }

            case '5': {
                daysFromPreviousMonth = 4;
                break;
            }

            case '6': {
                daysFromPreviousMonth = 5;
                break;
            }

        }
        var firstRenderDay = monthFirstDay.add('days', -1 * (daysFromPreviousMonth));
        this.weeks = ko.observableArray();
        this.weeks.push(new Week(moment(firstRenderDay), this));
        for(var i = 1; i < 5; i++) {
            var w = moment(moment(firstRenderDay.add('w', 1)));
            this.weeks.push(new Week(w, this));
        }
        this.categories = ko.observableArray([]);
        this.getDataFromServer();
        if(this.isAppointment) {
            this.getAppointmentsFromServer();
        }
    }
    ViewModel.prototype.set_self = function (_vm) {
        this.vm_self = _vm;
    };
    ViewModel.prototype.getAppointmentsFromServer = function () {
        var days = this.daysArray;
        var apiurl = $('#GetAppointmentsUrl');
        if(apiurl.length) {
            var url = apiurl.val();
            $.ajax({
                type: "GET",
                url: url,
                success: function (response) {
                    var apps = response.Apps;
                    for(var i = 0; i < apps.length; i++) {
                        apps[i].StartDate = moment(apps[i].StartDate);
                        apps[i].EndDate = moment(apps[i].EndDate);
                        for(var j = 0; j < days.length; j++) {
                            if(days[j].Date.format('YYYY-MM-DD') == apps[i].StartDate.format('YYYY-MM-DD')) {
                                var pushApp = new Appointment(moment().hours(9));
                                pushApp.StartDate(apps[i].StartDate);
                                pushApp.EndDate(apps[i].EndDate);
                                if(globalViewModel.role == "owner") {
                                    pushApp.Title(apps[i].Title);
                                    pushApp.Description(apps[i].Description);
                                    pushApp.Email(apps[i].Email);
                                    pushApp.Name(apps[i].Name);
                                    pushApp.Phone(apps[i].Phone);
                                    pushApp.URLCode = apps[i].URLCode;
                                }
                                days[j].Apps.push(pushApp);
                                break;
                            }
                        }
                    }
                },
                error: function (resp) {
                }
            });
        }
    };
    ViewModel.prototype.getDataFromServer = function () {
        var days = this.daysArray;
        var vm_categories = this.categories;
        var apiurl = $('#GetDataUrl');
        if(apiurl.length) {
            var url = apiurl.val();
            var success = true;
            $.ajax({
                type: "GET",
                url: url,
                success: function (response) {
                    success = true;
                    var entries = response.Entries;
                    var categories = response.Categories;
                    for(var i = 0; i < categories.length; i++) {
                        vm_categories.push(new Category(categories[i].ID, categories[i].Name, categories[i].Color));
                    }
                    for(var i = 0; i < entries.length; i++) {
                        entries[i].StartDate = moment(entries[i].StartDate);
                        entries[i].EndDate = moment(entries[i].EndDate);
                        for(var j = 0; j < days.length; j++) {
                            if(days[j].Date.format('YYYY-MM-DD') == entries[i].StartDate.format('YYYY-MM-DD')) {
                                var entryCategory = ko.utils.arrayFirst(vm_categories(), function (item) {
                                    return entries[i].CategoryID === item.ID;
                                });
                                var pushEntry = new Entry(entries[i], entryCategory);
                                days[j].Entries.push(pushEntry);
                                break;
                            }
                        }
                    }
                },
                error: function (resp) {
                    success = false;
                }
            });
        }
    };
    ViewModel.prototype.saveEntryToServer = function (entry) {
        var apiurl = $('#AddEntryUrl');
        if(apiurl.length) {
            var url = apiurl.val();
            var success = true;
            var serverEntry = new ServerEntry(entry);
            var myEntry = {
                Title: serverEntry.Title,
                Description: serverEntry.Description,
                StartDateString: entry.StartDate().format('YYYY-MM-DD HH:mm'),
                EndDateString: entry.EndDate().format('YYYY-MM-DD HH:mm'),
                IsAllDay: serverEntry.IsAllDay,
                CategoryID: serverEntry.Category.ID
            };
            $.ajax({
                type: "POST",
                url: url,
                data: ko.toJSON(myEntry),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (response) {
                    success = true;
                    entry.ID = response.ID;
                },
                error: function (resp) {
                    success = false;
                }
            });
            return success;
        }
    };
    ViewModel.prototype.saveAppointmentRequestToServer = function (app) {
        var apiurl = $('#AddAppointmentUrl');
        if(apiurl.length) {
            var url = apiurl.val();
            $.ajax({
                type: "POST",
                url: url,
                data: ko.toJSON(app),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (response) {
                    app.ID = response.ID;
                    app.URLCode = response.URLCode;
                },
                error: function (resp) {
                }
            });
        }
        return true;
    };
    ViewModel.prototype.refuseAppintment = function (app) {
        var apiurl = $('#RefuseAppointmentUrl');
        if(apiurl.length) {
            var url = apiurl.val();
            url += '/' + app.URLCode;
            $.ajax({
                type: "POST",
                url: url,
                success: function (response) {
                    if(response.success) {
                        return true;
                    } else {
                        return false;
                    }
                },
                error: function (resp) {
                    return false;
                }
            });
            return true;
        }
        return false;
    };
    ViewModel.prototype.acceptAppintment = function (app, newEntry) {
        var days = this.daysArray;
        var category = this.categories()[0];
        var apiurl = $('#AcceptAppointmentUrl');
        if(apiurl.length) {
            var url = apiurl.val();
            url += '/' + app.URLCode;
            $.ajax({
                type: "POST",
                url: url,
                success: function (response) {
                    if(response.success) {
                        var entry = response.entry;
                        entry.StartDate = moment(entry.StartDate);
                        entry.EndDate = moment(entry.EndDate);
                        newEntry.StartDate(entry.StartDate);
                        newEntry.EndDate(entry.EndDate);
                        newEntry.Title(entry.Title);
                        newEntry.Description(entry.Description);
                        newEntry.ID = entry.ID;
                        newEntry.Category(category);
                        return true;
                    } else {
                        return false;
                    }
                },
                error: function (resp) {
                    return false;
                }
            });
            return true;
        }
        return false;
    };
    return ViewModel;
})();
function StringToDate(text) {
    var n = Date.parse(text);
    return new Date(n);
}
$(function () {
    var year = $('#Year').val();
    var month = $('#Month').val();
    var role = $('#Role').val();
    var siteType = $('#SiteType').val();
    var vm5 = new ViewModel(year, month, role, siteType);
    globalViewModel = vm5;
    ko.applyBindings(vm5);
});
function updateViewModel() {
    var year = $('#Year').val();
    var month = $('#Month').val();
    var role = $('#Role').val();
    var siteType = $('#SiteType').val();
    ko.applyBindings(new ViewModel(year, month, role, siteType));
}
